package mirkofrancuski.battleship.game;

import java.util.HashMap;
import java.util.LinkedList;

import mirkofrancuski.battleship.db.IntTable;

import android.database.sqlite.SQLiteDatabase;

public class ComputerHard extends ComputerNormal {

	private final int carryMiss = -1;
	private final int carryHit = 10;

	private ProbabilityMatrix prior;

	private int totalHitNum;

	public ComputerHard() {
		super();

		prior = new ProbabilityMatrix(enemyBoard);
		prior.calculateEmpty();

		totalHitNum = 0;
	}

	@Override
	public Coordinates getShotCoordinates() {
		lastShot = null;

		LinkedList<Coordinates> maxArray = null;
		if (state == State.SEARCHING)
			maxArray = prior.getMax();
		else
			maxArray = prior.getMaxSurrounding(stack);

		lastShot = maxArray.get(randomGenerator.nextInt(maxArray.size()));
		stack.remove(lastShot);

		noOfShots++;

		return lastShot;
	}

	@Override
	public void resultFromLastShot(Cell cell) {
		if (cell == Cell.MISS) {
			if (state == State.SEARCHING)
				prior.calculateCell(lastShot, carryMiss);
			enemyBoard.updateResult(lastShot, cell);

		} else if (cell == Cell.HIT) {
			if (state == State.SEARCHING) {
				state = State.DESTROY;
				totalHitNum = 0;
			}
			prior.calculateCell(lastShot, carryHit);
			totalHitNum++;
			pushAllSidesToStack();
			enemyBoard.updateResult(lastShot, cell);

		}

	}

	@Override
	public void resultFromLastShot(Ship ship) {
		prior.updateShips(ship.shipCell);
		totalHitNum++;
		if (totalHitNum > ship.shipCell.getSize()) {
			prior.calculateCell(lastShot, carryHit);
			totalHitNum -= ship.shipCell.getSize();
			pushAllSidesToStack();
			enemyBoard.updateResult(ship);
		} else {
			state = State.SEARCHING;
			stack.clear();
			enemyBoard.updateResult(ship);
			if (prior.noShipsLeft())
				return;
			prior.recalculate();
		}
	}

	@Override
	public void placement() {
		myBoard.randomPlacement();
	}

	public void printProbability() {
		System.out.print(prior);
	}

	@Override
	public void save(SQLiteDatabase db) {
		super.save(db);

		String className = ComputerHard.class.toString();

		IntTable.addInt(db, className, "totalHitNum", totalHitNum);

		prior.save(db);

	}

	@Override
	public void restore(SQLiteDatabase db) {
		super.restore(db);

		String className = ComputerHard.class.toString();

		HashMap<String, Integer> hashMap = IntTable.getInts(db, className);
		totalHitNum = hashMap.get("totalHitNum");

		prior.restore(db);
	}

}
